package com.dc.toolkit.guava.base;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

/**
 * Description: Guava_Joiner测试类
 * @author: gdc
 * @date: 2021/4/17
 * @version 1.0
 */
@Slf4j
public class JoinerTest {

    /**
     * 不包含空的List
     */
    private final List<String> strList = Lists.newArrayList("Google", "Guava", "Scale", "Java");
    /**
     * 包含空的List
     */
    private final List<String> strListWithNullValue = Lists.newArrayList("Google", "Guava", "Scale", "Java", null);

    private final Map<String, String> strMap = new HashMap<String, String>() {
        {
            put("name","曹操");
            put("age","35");
        }
    };

    private static final String targetFileName = "D://testGuava.txt";
    private static final String targetFileNameToMap = "D://testGuavaToMap.txt";

    /**
     * Joiner.on().join()        将集合数据转换为 字符串
     */
    @Test
    public void testJoinOnJoin(){

        String result = Joiner.on("#").join(strList);
        Assert.assertEquals(result, "Google#Guava#Scale#Java");
    }

    /**
     * ## 当数据包含空信息时会  报错
     */
    @Test(expected = NullPointerException.class)
    public void testJoinOnJoinWithNullValue(){
        String result = Joiner.on("#").join(strListWithNullValue);
    }

    /**
     * Joiner.on().skipNulls()     当数据为空时跳过
     */
    @Test
    public void testJoinOnJoinWithNullValueButSkip(){
        String result = Joiner.on("#").skipNulls().join(strListWithNullValue);
        Assert.assertEquals(result, "Google#Guava#Scale#Java");
    }

    /**
     * Joiner.on().useForNull()     当数据为空时,设置默认的值
     */
    @Test
    public void testJoin_On_JoinWithNullValue_UseDefaultValue(){
        String result = Joiner.on("#").useForNull("DEFAULT").join(strListWithNullValue);
        Assert.assertEquals(result, "Google#Guava#Scale#Java#DEFAULT");
    }

    /**
     * Joiner.appendTo()
     * 传入的对象和返回的对象是同一个
     */
    @Test
    public void testJoin_On_Append_To_StringBuilder(){
        StringBuilder builder = new StringBuilder();

        StringBuilder resultBuilder = Joiner.on("#").useForNull("DEFAULT").appendTo(new StringBuilder(), strListWithNullValue);

        Assert.assertEquals(builder, resultBuilder);
        Assert.assertEquals(resultBuilder.toString(), "Google#Guava#Scale#Java#DEFAULT");
        Assert.assertEquals(builder.toString(), "Google#Guava#Scale#Java#DEFAULT");
    }

    /**
     * Joiner.appendTo()            将数据追加到文件中
     */
    @Test
    public void testJoin_On_Append_To_Writer(){
        try (FileWriter writer = new FileWriter(new File(targetFileName))){
            Joiner.on("#").useForNull("DEFAULT").appendTo(writer, strListWithNullValue);
            Assert.assertTrue(Files.isFile().test(new File(targetFileName)));
        } catch (IOException e) {
            fail("append to the writer occur fetal error");
        }
    }

    /**
     * 使用 JAVA_stream， 实现 Joiner 组装数据（跳过空值）功能
     */
    @Test
    public void testJoining_ByStream_SkipNullValue(){
        String result = strListWithNullValue.stream().filter(item -> !Strings.isNullOrEmpty(item)).collect(Collectors.joining("#"));
        Assert.assertEquals(result, "Google#Guava#Scale#Java");
    }

    /**
     * 使用 JAVA_stream， 实现 Joiner 组装数据（设置默认值）功能
     */
    @Test
    public void testJoining_ByStream_UseDefaultValue(){
        String result = strListWithNullValue.stream()
                .map(item -> Strings.isNullOrEmpty(item) ? "DEFAULT" : item)
                .collect(Collectors.joining("#"));
        Assert.assertEquals(result, "Google#Guava#Scale#Java#DEFAULT");
    }

    /**
     * Map 数据 转换为 字符串
     */
    @Test
    public void testJoin_On_WithMap(){
        String result = Joiner.on("#").withKeyValueSeparator("=").join(strMap);
        assertEquals(result, "name=曹操#age=35");
    }

    /**
     * Map 数据追加到 文件中
     */
    @Test
    public void testJoin_On_WithMapToAppendable(){
        try (FileWriter writer = new FileWriter(new File(targetFileNameToMap))){
            Joiner.on("#").withKeyValueSeparator("=").appendTo(writer, strMap);
            Assert.assertTrue(Files.isFile().test(new File(targetFileNameToMap)));
        } catch (IOException e) {
            fail("append to the writer occur fetal error");
        }
    }
}
